from sqlalchemy import Column, Integer, String, Boolean, DateTime, Text, ForeignKey, Enum, JSON
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from app.database import Base
import enum


class JobStatus(str, enum.Enum):
    """作业状态枚举"""
    DRAFT = "draft"          # 草稿
    SCHEDULED = "scheduled"  # 已调度
    RUNNING = "running"      # 运行中
    SUCCESS = "success"      # 成功
    FAILED = "failed"        # 失败
    PAUSED = "paused"        # 暂停
    CANCELLED = "cancelled"  # 取消


class JobType(str, enum.Enum):
    """作业类型枚举"""
    SCRIPT = "script"        # 脚本作业
    SQL = "sql"             # SQL 作业
    DATA_SYNC = "data_sync"  # 数据同步作业
    API_CALL = "api_call"    # API 调用作业


class TriggerType(str, enum.Enum):
    """触发器类型枚举"""
    CRON = "cron"           # 定时触发
    MANUAL = "manual"       # 手动触发
    EVENT = "event"         # 事件触发
    DEPENDENCY = "dependency"  # 依赖触发


class Job(Base):
    """作业模型"""
    __tablename__ = "jobs"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String(100), nullable=False, index=True)
    description = Column(Text, nullable=True)
    job_type = Column(Enum(JobType), nullable=False)
    status = Column(Enum(JobStatus), default=JobStatus.DRAFT)
    
    # 作业配置
    config = Column(JSON, nullable=True)  # 作业配置 JSON
    trigger_type = Column(Enum(TriggerType), default=TriggerType.MANUAL)
    cron_expression = Column(String(100), nullable=True)  # Cron 表达式
    timeout = Column(Integer, default=3600)  # 超时时间（秒）
    max_retries = Column(Integer, default=0)  # 最大重试次数
    retry_delay = Column(Integer, default=300)  # 重试延迟（秒）
    
    # 关联信息
    script_id = Column(Integer, ForeignKey("scripts.id"), nullable=True)
    creator_id = Column(Integer, ForeignKey("users.id"), nullable=False)
    folder_id = Column(Integer, ForeignKey("job_folders.id"), nullable=True)
    
    # Airflow 相关
    dag_id = Column(String(100), unique=True, nullable=True)  # 对应的 DAG ID
    is_active = Column(Boolean, default=True)
    
    # 时间戳
    created_at = Column(DateTime(timezone=True), server_default=func.now())
    updated_at = Column(DateTime(timezone=True), onupdate=func.now())
    last_run_time = Column(DateTime(timezone=True), nullable=True)
    next_run_time = Column(DateTime(timezone=True), nullable=True)
    
    # 关系
    script = relationship("Script")
    creator = relationship("User", back_populates="jobs")
    folder = relationship("JobFolder", back_populates="jobs")
    executions = relationship("JobExecution", back_populates="job")
    dependencies = relationship("JobDependency", 
                               foreign_keys="JobDependency.job_id",
                               back_populates="job")
    dependents = relationship("JobDependency", 
                             foreign_keys="JobDependency.depends_on_job_id",
                             back_populates="depends_on_job")


class JobFolder(Base):
    """作业文件夹模型"""
    __tablename__ = "job_folders"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String(100), nullable=False)
    description = Column(Text, nullable=True)
    parent_id = Column(Integer, ForeignKey("job_folders.id"), nullable=True)
    creator_id = Column(Integer, ForeignKey("users.id"), nullable=False)
    created_at = Column(DateTime(timezone=True), server_default=func.now())
    
    # 关系
    parent = relationship("JobFolder", remote_side=[id])
    children = relationship("JobFolder")
    jobs = relationship("Job", back_populates="folder")
    creator = relationship("User")


class JobExecution(Base):
    """作业执行记录模型"""
    __tablename__ = "job_executions"

    id = Column(Integer, primary_key=True, index=True)
    job_id = Column(Integer, ForeignKey("jobs.id"), nullable=False)
    run_id = Column(String(100), nullable=False)  # Airflow run_id
    
    # 执行信息
    status = Column(Enum(JobStatus), default=JobStatus.RUNNING)
    trigger_type = Column(String(20), nullable=True)  # 触发方式
    start_time = Column(DateTime(timezone=True), server_default=func.now())
    end_time = Column(DateTime(timezone=True), nullable=True)
    duration = Column(Integer, nullable=True)  # 执行时长（秒）
    
    # 执行结果
    output = Column(Text, nullable=True)
    error_message = Column(Text, nullable=True)
    exit_code = Column(Integer, nullable=True)
    
    # 资源使用情况
    cpu_usage = Column(String(50), nullable=True)
    memory_usage = Column(String(50), nullable=True)
    
    # 执行参数
    parameters = Column(JSON, nullable=True)
    
    # 关系
    job = relationship("Job", back_populates="executions")


class JobDependency(Base):
    """作业依赖关系模型"""
    __tablename__ = "job_dependencies"

    id = Column(Integer, primary_key=True, index=True)
    job_id = Column(Integer, ForeignKey("jobs.id"), nullable=False)
    depends_on_job_id = Column(Integer, ForeignKey("jobs.id"), nullable=False)
    
    # 依赖条件
    condition = Column(String(20), default="success")  # success, failed, completed
    created_at = Column(DateTime(timezone=True), server_default=func.now())
    
    # 关系
    job = relationship("Job", foreign_keys=[job_id], back_populates="dependencies")
    depends_on_job = relationship("Job", foreign_keys=[depends_on_job_id], back_populates="dependents")


class JobAlert(Base):
    """作业告警配置模型"""
    __tablename__ = "job_alerts"

    id = Column(Integer, primary_key=True, index=True)
    job_id = Column(Integer, ForeignKey("jobs.id"), nullable=False)
    
    # 告警配置
    alert_type = Column(String(20), nullable=False)  # success, failed, timeout, retry
    is_enabled = Column(Boolean, default=True)
    recipients = Column(Text, nullable=False)  # 接收人邮箱列表，逗号分隔
    message_template = Column(Text, nullable=True)
    
    created_at = Column(DateTime(timezone=True), server_default=func.now())
    updated_at = Column(DateTime(timezone=True), onupdate=func.now())
    
    # 关系
    job = relationship("Job")


class JobMonitor(Base):
    """作业监控指标模型"""
    __tablename__ = "job_monitors"

    id = Column(Integer, primary_key=True, index=True)
    job_id = Column(Integer, ForeignKey("jobs.id"), nullable=False)
    execution_id = Column(Integer, ForeignKey("job_executions.id"), nullable=False)
    
    # 监控指标
    timestamp = Column(DateTime(timezone=True), server_default=func.now())
    cpu_percent = Column(String(10), nullable=True)
    memory_mb = Column(Integer, nullable=True)
    disk_io_read = Column(Integer, nullable=True)
    disk_io_write = Column(Integer, nullable=True)
    network_in = Column(Integer, nullable=True)
    network_out = Column(Integer, nullable=True)
    
    # 关系
    job = relationship("Job")
    execution = relationship("JobExecution") 